﻿// -----------------------------------------------------------------------
//  <copyright file="ConnectionUserCache.cs" company="LiuliuSoft">
//      Copyright (c) 2025 66SOFT. All rights reserved.
//  </copyright>
//  <site>https://ifs.66soft.net</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2025-09-27 22:09</last-date>
// -----------------------------------------------------------------------

using Microsoft.Extensions.Caching.Distributed;

using OSharp.Caching;


namespace DaprPlus.AspNetCore.SignalR;

public class ConnectionUserCache(IDistributedCache cache) : IConnectionUserCache
{
    public Task<ConnectionUser?> GetUserAsync(string userName)
    {
        Check.NotNullOrEmpty(userName, nameof(userName));

        var key = GetKey(userName);
        return cache.GetAsync<ConnectionUser?>(key);
    }

    public async Task<string[]> GetConnectionIds(string userName)
    {
        var user = await GetUserAsync(userName);
        return user?.ConnectionIds.ToArray() ?? [];
    }

    public async Task SetUser(string userName, ConnectionUser user)
    {
        var key = GetKey(userName);
        await cache.SetAsync(key, user);
    }

    public async Task AddConnectionId(string userName, string connectionId)
    {
        var user = await GetUserAsync(userName) ?? new ConnectionUser { UserName = userName };
        user.ConnectionIds.AddIfNotExist(connectionId);
        await SetUser(userName, user);
    }

    public async Task RemoveConnectionId(string userName, string connectionId)
    {
        var user = await GetUserAsync(userName);
        if (user == null || !user.ConnectionIds.Contains(connectionId))
        {
            return;
        }

        user.ConnectionIds.Remove(connectionId);
        if (user.ConnectionIds.Count == 0)
        {
            await RemoveUser(userName);
        }
        else
        {
            await SetUser(userName, user);
        }
    }

    public Task RemoveUser(string userName)
    {
        var key = GetKey(userName);
        return cache.RemoveAsync(key);
    }

    private static string GetKey(string userName)
    {
        return "Share:SignalR:User:" + userName;
    }
}